from math import ceil
from copy import deepcopy
from scipy.io import wavfile

import pylab as p
import constants as c
import filter as f
import click_detector as cd
import utils as u
import time as t

#------------------------------------------------
# Script Principal
#------------------------------------------------
print("Iniciando ejecucion...")
tic = t.time()

# Cargo la senial a procesar
u.Log("Cargando datos del archivo de audio...", 1)
fs, data = wavfile.read(c.DATA_PATH + c.DATA_NAME)

# Crear el filtro
u.Log("Generando filtro FIR...", 1)
filter_coef = f.createFIRFilter(Fs = fs, FPass = c.FIR_PASS, N = c.FIR_N)
filter_delay = (len(filter_coef) - 1) / 2

# copia de respaldo de la senal original
u.Log("Realizando copia de datos originales...", 1)
data_original = deepcopy(data)

# Determinar cantidad de segmentos en los cuales se dividira la data 
u.Log("Calculando cantidad de segmentos...", 1)
segment_count = int(ceil((len(data) * 1.0) / c.SEG_SIZE))

# Cantidad de realimentacion por el filtro
for i in xrange(c.ITERATIONS):
    u.Log("Iteracion " + str(i + 1), 1)

    trailing = []    
    template_limits = []
    filtered_signal = []
    filter_fft = []
    
    # Descomponer en segmentos de largo L_WIDTH
    for j in xrange(segment_count):
        u.Log("--Segmento " + str(j + 1), 1)
        segment = data[j * c.SEG_SIZE : (j + 1) * c.SEG_SIZE]
     
        # Obtener la salida del filtro mediante el metodo escogido
        if c.FILT_TYPE == 'conv':
            filtered_segment, trailing = u.filterSignalConvolution(filter_coef, segment, j, trailing, segment_count)
        elif c.FILT_TYPE == 'fft':
            filtered_segment, trailing, filter_fft = u.filterSignalFFT(filter_coef, segment, j, trailing, segment_count, filter_fft)
        
        # Si se quiere ver la salida del filtro, reconstruir la senial completa
        if (c.PLOT_FILTER_OUTPUT == 1):
            if (j < (segment_count - 1)):
                # Ir concatenando los segmentos filtrados para obtener la senial filtrada completa
                filtered_signal = p.concatenate((filtered_signal, filtered_segment[0 : c.SEG_SIZE]))
            else:
                # En el ultimo caso, agregar toda la senial ya que no vendran mas segmentos
                filtered_signal = p.concatenate((filtered_signal, filtered_segment))
                
        template_limits_temp = cd.detectAndFixClicks(segment, filtered_segment, fs, filter_delay)
     
        # Si se van a mostrar los graficos de los clicks detectados por iteracion, almacenar los clicks de cada segmento
        if (c.PLOT_ITERATIONS == 1):   
            # Correr los limites para que sea de los datos y no del segmento
            template_limits += u.shiftArray(template_limits_temp, j * c.SEG_SIZE)
    
    if (c.PLOT_FILTER_OUTPUT == 1):
        u.showFilterOutput(filtered_signal, fs, Figure = 10)
            
    if (c.PLOT_ITERATIONS == 1):
        u.showIterationResults(data_original, data, fs, template_limits, Figure = 1)
        p.show()


u.Log("Generando nuevo archivo de audio...", 1)
wavfile.write(c.DATA_PATH + "salida_" + c.DETECT_TYPE + "_" + c.FILT_TYPE + ".wav", fs, data)
    
if c.PLOT_SIGNAL_RESULT == 1:
    u.showOutput(data_original, data, fs, Figure = 1)
    u.showOutputComparison(data_original, data, fs, Figure = 3)

if (c.PLOT_FIR_FILTER == 1):
    u.showFIRFilter(fs, filter_coef, Figure = 4)

if (c.PLOT_IIR_FILTERS == 1):
    u.showIIRFilter(Fs = fs, FPass = 4500, FStop = 2500, GPass = 0.1, GStop = 60.0, Figure = 8)

if (c.PLOT_SMOOTHING_WINDOW == 1):
    u.showSmoothingWindow(Figure = 11)

toc = t.time()
print("Ejecucion completa finalizada (" + str(toc-tic) + "s)")

p.show()
